﻿#include "VTLPCLCamera.h"
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkAxesActor.h>
#include <vtkOBJReader.h>
#include <vtkCamera.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/io/vtk_io.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/passthrough.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/kdtree/kdtree_flann.h> 
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/surface/poisson.h>
#include <pcl/surface/mls.h>
#include <pcl/surface/marching_cubes_hoppe.h>
#include <pcl/surface/marching_cubes_rbf.h>

void VTLPCLCamera::ClickPickCallBack(const pcl::visualization::PointPickingEvent& et, void* args)
{
	auto cv = reinterpret_cast<VTLPCLCamera*>(args);
	pcl::PointXYZ point;
	if (et.getPointIndex() == -1 || !cv->isSelect)
	{
		return;
	}
	et.getPoint(point.x, point.y, point.z);
	// 设置vtkWidget相机看向的位置
	cv->vtkWidget->renderWindow()
		->GetRenderers()->GetFirstRenderer()
		->GetActiveCamera()->SetFocalPoint(point.x, point.y, point.z);
	
	// 获取点云
	auto clouds = cv->viewer->getCloudActorMap();
	// 根据点云名字查找点云
	auto cloudIter = clouds->find("clickedPoints");

	if (cloudIter == clouds->end()) {
		cv->cloudCenter.reset(new pcl::PointCloud<pcl::PointXYZ>);
		cv->viewer->addPointCloud<pcl::PointXYZ>(cv->cloudCenter, "clickedPoints");
		cv->viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clickedPoints");
	}
	//清空
	cv->cloudCenter->clear();
	cv->cloudCenter->push_back(point);
	// Draw clicked points in red:
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> red(cv->cloudCenter, 255, 0, 0);
	// 更新点云
	cv->viewer->updatePointCloud<pcl::PointXYZ>(cv->cloudCenter, red, "clickedPoints");
	qDebug() << point.x << " " << point.y << " " << point.z;
}

void VTLPCLCamera::KeyboardCallBack(const pcl::visualization::KeyboardEvent& et, void* args) {
	if (et.getKeySym() == "s")
	{
		auto cv = reinterpret_cast<VTLPCLCamera*>(args);
		cv->isSelect = !cv->isSelect;
	}
}

VTLPCLCamera::VTLPCLCamera(QWidget* parent)
	: QMainWindow(parent)
{
	vtkWidget = new QVTKOpenGLNativeWidget(this);
	this->resize(600, 400);
	this->setCentralWidget(vtkWidget);

	cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);

	// PCL读取.pcb点云文件
	pcl::io::loadPCDFile("D:/TEST/3D/pcb/rabbit.pcd", *cloud);

	auto renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
	auto renderer = vtkSmartPointer<vtkRenderer>::New();
	renderWindow->AddRenderer(renderer);
	//// PCL 点云显示到VTK
	viewer = pcl::visualization::PCLVisualizer::Ptr(new pcl::visualization::PCLVisualizer(
		renderer
		, renderWindow, "", false));
	viewer->addPointCloud(cloud, "cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud");
	// 坐标系
	//viewer->addCoordinateSystem(1.0);

	// VTK 点云显示到VTK
	vtkWidget->setRenderWindow(viewer->getRenderWindow());
	viewer->setupInteractor(vtkWidget->interactor(), vtkWidget->renderWindow());
	//将点云点击事件函数注册给视窗
	viewer->registerPointPickingCallback(ClickPickCallBack,
		(void*)this);
	//将点云键盘事件函数注册给视窗
	viewer->registerKeyboardCallback(KeyboardCallBack,
		(void*)this);
}



VTLPCLCamera::~VTLPCLCamera()
{
	vtkWidget->interactor()->SetRenderWindow(nullptr);
	vtkWidget->interactor()->SetInteractorStyle(nullptr);
}
